#pragma once
#include <string>
#include <memory>  // std::auto_ptr
#include <cstdlib> // std::exit
#include <iostream>
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include "logger.hpp"
#include "chat_session.hxx"
#include "chat_session-odb.hxx"
#include "mysql_chat_session_member.hpp"
#include "mysql.hpp"

namespace zrb
{
    // 使用ODB框架对会话成员表的操作
    class ChatSessionTable
    {
    public:
        using ptr = std::shared_ptr<ChatSessionTable>;
        ChatSessionTable(const std::shared_ptr<odb::core::database> &db)
            : _db(db)
        {
        }

        // 新增会话
        bool insert(Chat_Session &cs)
        {
            try
            {
                // 3.获取事务对象开启事务
                odb::transaction trans(_db->begin());
                _db->persist(cs);
                // 4.提交事务
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("新增会话数据出错：{}", e.what());
                return false;
            }
            return true;
        }

        // 删除会话
        bool remove(const std::string &ssid)
        {
            try
            {
                // 3.获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<Chat_Session> query;
                typedef odb::result<Chat_Session> result;
                _db->erase_query<Chat_Session>(query::session_id == ssid); // 删除条件

                typedef odb::query<Session_member> query1;
                _db->erase_query<Session_member>(query1::session_id == ssid); // 删除一个会话的时候，该会话里面的会话成员也要删除
                // 4.提交事务
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("删除会话数据出错：{}", e.what());
                return false;
            }
            return true;
        }

        bool remove(const std::string &uid, const std::string &pid)
        {
            // 单聊会话的删除，-- 根据单聊会话的两个成员
            try
            {
                odb::transaction trans(_db->begin());
                typedef odb::query<SingleChatSession> query;
                typedef odb::result<SingleChatSession> result;
                auto res = _db->query_one<SingleChatSession>(
                    query::csm1::user_id == uid &&
                    query::csm2::user_id == pid &&
                    query::css::chat_session_type == ChatSessionType::SINGLE);

                std::string cssid = res->chat_session_id;
                typedef odb::query<Chat_Session> cquery;
                _db->erase_query<Chat_Session>(cquery::session_id == cssid);

                typedef odb::query<Session_member> mquery;
                _db->erase_query<Session_member>(mquery::session_id == cssid);
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("删除会话失败 {}-{}:{}！", uid, pid, e.what());
                return false;
            }
            return true;
        }

        // 通过会话 ID，获取会话的详细信息
        std::shared_ptr<Chat_Session> select(const std::string &ssid)
        {
            std::shared_ptr<Chat_Session> res;
            try
            {
                // 获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<Chat_Session> query;
                typedef odb::result<Chat_Session> result;
                res.reset(_db->query_one<Chat_Session>(query::session_id == ssid));
                // 5. 提交事务
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("通过会话获取会话数据信息出错：{}", e.what());
            }
            return res;
        }

        // 通过用户 ID 获取所有的好友单聊会话（连接会话成员表和用户表）
        std::vector<SingleChatSession> singleChatSession(const std::string &uid)
        {
            std::vector<SingleChatSession> res;
            try
            {
                // 获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<SingleChatSession> query;
                typedef odb::result<SingleChatSession> result;

                // 查询
                result r(_db->query<SingleChatSession>(query::css::chat_session_type == ChatSessionType::SINGLE &&
                                                       query::csm1::user_id == uid &&
                                                       query::csm2::user_id != query::csm1::user_id));

                // 遍历
                for (auto it = r.begin(); it != r.end(); ++it)
                {
                    res.push_back(*it);
                }
                // 5. 提交事务
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("通过用户单聊会话出错：{}", e.what());
            }
            return res;
        }

        // 通过用户 ID 获取所有自己的群聊会话（连接会话成员表和用户表）
        std::vector<GroupChatSession> groupChatSession(const std::string &uid)
        {
            std::vector<GroupChatSession> res;
            try
            {
                // 获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<GroupChatSession> query;
                typedef odb::result<GroupChatSession> result;

                // 查询
                result r(_db->query<GroupChatSession>(query::css::chat_session_type == ChatSessionType::GROUP &&
                                                      query::csm::user_id == uid));

                // 遍历
                for (auto it = r.begin(); it != r.end(); ++it)
                {
                    res.push_back(*it);
                }
                // 5. 提交事务
                trans.commit();
            }
            catch (std::exception &e)
            {
                LOG_ERROR("通过用户群聊会话出错：{}", e.what());
            }
            return res;
        }

    private:
        std::shared_ptr<odb::core::database> _db;
    };
}